package bancosys.tec.persist.audit.dao;

import org.hibernate.Criteria;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import bancosys.tec.persist.audit.domain.AuditVersion;
import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dataset.HibernateRandomAccessResultSet;
import bancosys.tec.persist.persister.PersistenceAction;
import bancosys.tec.utils.date.Timestamp;

/**
 * @created 03/10/2007
 * @author Gustavo Almeida
 */
public class AuditVersionDAO extends BaseDAO<AuditVersion> {

    /**
     * Cria um <code>version</code>
     * 
     * @param action ação da persistência.
     * @param user usuário que gerou a modificação.
     * @param modificationSource fonte da modificação.
     * @return <code>version</code>
     */
    public AuditVersion createBean(PersistenceAction action, String user, String modificationSource) {
        AuditVersion version = this.createBean();
        version.setAction(action);
        version.setUser(user);
        version.setModificationSource(modificationSource);
        return version;
    }

    /**
     * Devolve uma lista das entidades cujas propriedades estão de acordo com o exemplo e os outros dados passados como parâmetros.
     * 
     * @param example o exemplo
     * @param className o nome da classe auditada.
     * @param user o usuário autenticador
     * @param beginDate a data inicial dos registros.
     * @param endDate a data final dos registros.
     * @return a lista das entidades.
     */
    @Deprecated
    public HibernateRandomAccessResultSet<AuditVersion> findResultSetByClassByNameByDate(AuditVersion example, String className,
            String user, Timestamp beginDate, Timestamp endDate) {
        Criteria crit = this.getSession().createCriteria(this.getPersistableClass());
        Example ex = this.mountExample(example, false, "ts");
        crit.add(ex);
        crit.createAlias("entity", "e").add(Restrictions.eq("e.className", className))
                .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

        if (user != null && !"".equals(user)) {
            crit.add(Restrictions.eq("user", user));
        }
        if (beginDate != null) {
            crit.add(Restrictions.ge("ts", beginDate));
        }
        if (endDate != null) {
            crit.add(Restrictions.le("ts", endDate));
        }

        crit.addOrder(Order.asc("ts"));

        return new HibernateRandomAccessResultSet<AuditVersion>(this.getSession(), crit);
    }

    /**
     * Devolve uma lista das entidades cujas propriedades estão de acordo com o exemplo e os outros dados passados como parâmetros (aceita
     * className nulo, trazendo ocorrências de todas as entidades auditáveis). Ordenando por ordem cronológica decrescente.
     * 
     * @param example o exemplo
     * @param className o nome da classe auditada.
     * @param user o usuário autenticador
     * @param beginDate a data inicial dos registros.
     * @param endDate a data final dos registros.
     * @return a lista das entidades.
     */
    @SuppressWarnings("deprecation")
    public HibernateRandomAccessResultSet<AuditVersion> findResultSetByClassByNameByDateReverseSorted(AuditVersion example,
            String className, String user, Timestamp beginDate, Timestamp endDate) {
        Criteria crit = this.getSession().createCriteria(this.getPersistableClass());
        Example ex = this.mountExample(example, false, "ts");
        crit.add(ex);
        if (className != null) {
            crit.createAlias("entity", "e").add(Restrictions.eq("e.className", className))
                    .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        }

        if (user != null && !"".equals(user)) {
            crit.add(Restrictions.eq("user", user));
        }
        if (beginDate != null) {
            crit.add(Restrictions.ge("ts", beginDate));
        }
        if (endDate != null) {
            crit.add(Restrictions.le("ts", endDate));
        }

        crit.addOrder(Order.desc("ts"));

        return new HibernateRandomAccessResultSet<AuditVersion>(this.getSession(), crit);
    }
}
